package com.qili.core.quartz.CustomQuartz;

import cn.hutool.core.util.IdUtil;
import com.qili.core.utils.DictTypes;
import com.qili.entity.base.BaseDict;
import com.qili.entity.supervisor.ProjectNotice;
import com.qili.entity.supplier.SupplierProject;
import com.qili.entity.supplier.SupplierProjectAccept;
import com.qili.entity.supplier.dto.SupplierProjectAcceptDTO;
import com.qili.entity.supplier.dto.SupplierProjectDTO;
import com.qili.entity.sys.SysUser;
import com.qili.entity.sys.SysUserWorkExperience;
import com.qili.entity.sys.dto.SysUserDTO;
import com.qili.redis.RedisService;
import com.qili.service.SysUserService;
import com.qili.service.base.BaseCompanyService;
import com.qili.service.base.BaseDictService;
import com.qili.service.supervisor.ProjectNoticeServie;
import com.qili.service.supplier.RecommendReasonService;
import com.qili.service.supplier.SupplierProjectAcceptService;
import com.qili.service.supplier.SupplierProjectManagerService;
import com.qili.service.supplier.SupplierProjectPubNoticeService;
import com.qili.service.sys.SysUserWorkExperienceService;
import com.qili.util.DateUtil;
import com.qili.util.StringUtil;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author zhaoyongke
 * @date 2021/4/7 每天执行一次-------招标截止日的下午17:30 执行
 * 情形2、到招标截止时间，有一人应接：则推荐此人为中标人。
 * 情形3、到招标截止时间（招标截止日的下午17:30），多人应接：平台自动判断项目应接人列表的实施费用信息，如果有最低价则选择最低价，如果有多家相同的最低价，则给最低价的应接人发送议价通知：您应接的XXX项目进入议价环节，请填写您接受的最低实施费用，应接人收到通知可以提交接受的最低实施费用，然后提交，更新到应答列表中。设置X日后不响应则自动默认之前的费用。所有最低价应接人提交完成或X日后自动进行第二次比价，最多进行三次比价，如果还是有相同的则系统自动推荐应接人中综合评分排行第一的为中标人。
 * 其中X后台设置，X从招标截止时间往后计算，可以设置小数位数值，比如0.5日。
 * <p>
 * 系统推荐出项目中标人后推送消息给 【中标审核人】角色：XXX项目拟中标人为XXX，请确认是否同意。若选择同意，则中标人确定，若不同意，则由 【中标审核人】 自行选择，若是多个【中标审核人】意见不一致则提示：审核意见不统一，请达成一致后操作。然后所有【中标审核人】操作且结果一致后则中标人确定。若Y日内未确认，则默认同意推荐结果。
 * 项目中标人确定后推送消息给发布人：您发布的XXX项目中标人为XXX。
 */
@Log
public class NbYJZbAndYJFirstNoticeJob implements Job {
    @Autowired
    SysUserService sys;
    @Autowired
    private SupplierProjectPubNoticeService supplierProjectPubNoticeService;
    @Autowired
    private SupplierProjectManagerService supplierProjectManagerService;
    @Autowired
    BaseDictService baseDictService;
    @Autowired
    ProjectNoticeServie projectNoticeServie;
    @Autowired
    SupplierProjectAcceptService supplierProjectAcceptService;
    @Autowired
    SysUserService sysUserService;
    @Autowired
    BaseCompanyService baseCompanyService;
    @Autowired
    private RecommendReasonService recommendReasonService;

    @Autowired
    SysUserWorkExperienceService userWorkExperienceService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;



    /**
     * 每天下午  17:30 分执行
     */


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("NbYJZbAndYJFirstNoticeJob：启动任务=======================");
        run();
        System.out.println("NbYJZbAndYJFirstNoticeJob：下次执行时间=====" +
                new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
                        .format(context.getNextFireTime()) + "==============");
    }

    public void run() {

        log.info("NbYJZbAndYJFirstNoticeJob=======开始==================================");
        String lockkey = "NbYJZbAndYJFirstNoticeJob_key";
        String uuId = IdUtil.simpleUUID();
        try {
            lock(lockkey,uuId);
        //(2)到招标截止时间，有一人应接：则推荐此人为中标人。
           saveSendXfZbjzRiqi();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }finally {
            unlock(lockkey,uuId);
        }
    }

    /**
     * @param
     * @Author:zhaoyongke
     * @Description: 到招标截止时间，有一人应接：则推荐此人为中标人。
     * @Date:16:09 2021/4/12
     */
    public void saveSendXfZbjzRiqi() {


        try {
            SupplierProjectDTO  dtopro=new SupplierProjectDTO();
            dtopro.setStatus("006");
            dtopro.setPublishType("001");
            dtopro.setYjStatusNo("0");
            dtopro.setTjStatusNo("0");
            List<SupplierProjectDTO> supplierProjects =supplierProjectManagerService.selectProject(dtopro);

/*            Example e = new Example(SupplierProject.class);
            Example.Criteria c = e.createCriteria();
            c.andEqualTo("status", "006");
            c.andEqualTo("publishType", "001");
            c.andEqualTo("yjStatus", "0");
            //没有推荐中标人的项目
            c.andEqualTo("tjStatus", "0");
            List<SupplierProject> supplierProjects = supplierProjectManagerService.selectByExample(e);*/
            for (int i = 0; i < supplierProjects.size(); i++) {
                System.out.println(111);
                SupplierProject project = supplierProjects.get(i);
                String zbDate = project.getZbEndDate();
                Date zbEndDate = DateUtil.parseDate(zbDate, "yyyy-MM-dd HH:mm");
                Date currdate = new Date();
                if (currdate.after(zbEndDate)) {
                    recommendReasonService.insertComparison(project.getSupProjectId());
                    System.out.println(222);
                    Boolean isyj = false;
                    // 到了 招标截止时间
                    SupplierProjectAcceptDTO acceptDTO = new SupplierProjectAcceptDTO();
                    acceptDTO.setSupProjectId(project.getSupProjectId());
                    acceptDTO.setScoreDesc("desc");
                    List<SupplierProjectAcceptDTO> acceptlist = supplierProjectAcceptService.selectListByScore(acceptDTO);
                    if (acceptlist.size() == 1) {
                        System.out.println(333);

                        // 有一人应接的情况   推荐中标
                        ProjectNotice notice = new ProjectNotice();
                        notice.setLinkId(project.getSupProjectId());
                        notice.setNoticeType("107");
                        int y1 = projectNoticeServie.selectCount(notice);
                        if (y1 == 0) {
                            sendNoticeToXfTjzb(project, acceptlist.get(0));
                        }
                        project.setTjStatus("1");// 结束
                        project.setTjPerson(acceptlist.get(0).getAcceptBy());
                        project.setTjDate(DateUtil.getCurrentDateString("yyyy-MM-dd HH:mm"));
                        supplierProjectManagerService.updateByPrimaryKey(project);

                    } else if (acceptlist.size() > 1) {
                        System.out.println(4444);
                        //有最低价选择最低价  推荐中标
                        SupplierProjectAcceptDTO dto = new SupplierProjectAcceptDTO();
                        dto.setSupProjectId(project.getSupProjectId());
                        List<SupplierProjectAcceptDTO> supplierProjectAcceptDTOS = supplierProjectAcceptService.selectAcceptByScore(dto);
                        SupplierProjectAcceptDTO acceptDTO1 = supplierProjectAcceptDTOS.get(0);
                        String num = acceptDTO1.getNum();
                        if ("1".equals(num)) {
                            System.out.println(5555);
                            //推荐最低价
                            String totalMoney = acceptDTO1.getTotalMoney();
                            SupplierProjectAccept accpet = new SupplierProjectAccept();
                            accpet.setSupProjectId(project.getSupProjectId());
                            accpet.setTotalMoney(totalMoney);
                            List<SupplierProjectAccept> select = supplierProjectAcceptService.select(accpet);
                            if (select.size() > 0) {
                                ProjectNotice notice = new ProjectNotice();
                                notice.setLinkId(project.getSupProjectId());
                                notice.setNoticeType("107");
                                int y1 = projectNoticeServie.selectCount(notice);
                                if (y1 == 0) {
                                    SupplierProjectAccept accept = select.get(0);
                                    sendNoticeToXfTjzb(project, accept);
                                    project.setTjPerson(accept.getAcceptBy());
                                }
                            }
                            project.setTjStatus("1");// 结束
                            project.setTjDate(DateUtil.getCurrentDateString("yyyy-MM-dd HH:mm"));
                            supplierProjectManagerService.updateByPrimaryKey(project);
                        } else {
                            System.out.println(666);
                            //如果有多家相同的最低价，则给最低价的应接人发送议价通知
                            // 2021 0908 给所有人 发送 议价通知
                            String totalMoney = acceptDTO1.getTotalMoney();
                            SupplierProjectAcceptDTO fjydto = new SupplierProjectAcceptDTO();
//                            fjydto.setTotalMoney(totalMoney);
                            fjydto.setSupProjectId(project.getSupProjectId());
                            List<SupplierProjectAccept> select = supplierProjectAcceptService.select(fjydto);
                            ArrayList<String> jypersonlist = new ArrayList<>();
                            for (int j = 0; j < select.size(); j++) {
                                SupplierProjectAccept accept = select.get(j);
                                // 发送议价通知
                                supplierProjectManagerService.sendNoticeToYj(project, accept, "FIrst定时器生成议价");
                                isyj = true;
                                jypersonlist.add(accept.getAcceptBy());
                            }
                            if (isyj) {
                                String jypersonliststr = jypersonlist.toString();
                                String yjperson = "";
                                if (StringUtil.isNotBlank(jypersonliststr)) {
                                    //截取前后【】
                                    yjperson = jypersonliststr.replaceAll("\\[", "").replaceAll("\\]", "");
                                }
                                project.setYjPerson(yjperson);
                            }

                        }

                    }
                    if (isyj) {
                        System.out.println(8888);
                        project.setYjStatus("1");
                        project.setYjNum(1);
                        project.setYjDate(DateUtil.getCurrentDateString("yyyy-MM-dd HH:mm"));
                        supplierProjectManagerService.updateByPrimaryKey(project);
                    }
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }


    }

    /**
     * @param project
     * @Author:zhaoyongke
     * @Description:
     * @Date:15:45 2021/4/12
     */
    public void sendNoticeToXfTjzb(SupplierProject project, SupplierProjectAccept accept)  throws   Exception {
        // 系统推荐出项目中标人后推送消息给 【中标审核人】角色 zbCheckPerson
        List<SysUser> sysUsers = getCheckUsers("zbCheckPerson", project);
        if(!CollectionUtils.isEmpty(sysUsers)){
            for (int i = 0; i < sysUsers.size(); i++) {
                String acceptBy = accept.getAcceptBy();
                SysUser sysUser = sysUserService.selectByPrimaryKey(acceptBy);
                String personType = sysUser.getPersonType();
                String realName = "";
                if ("001".equals(personType)) {
                    // 个人
                    realName = sysUser.getRealName();
                } else {
                    realName = sysUser.getLinkPerson();
                }
                ProjectNotice notice = new ProjectNotice();
                notice.setLinkId(project.getSupProjectId());
                notice.setIsView("0");
                notice.setSendTo(sysUsers.get(i).getId());
                notice.setTitle(project.getProjectName() + "项目推荐中标人为" + realName + "，请确认是否同意");
                notice.setNoticeType("107");// 内部单位推荐
                notice.setApplicantType("002");// 供需
                notice.setContent(project.getProjectName());
                notice.setCreateDate(DateUtil.getCurrentDateString());
                notice.setTjPerson(acceptBy);
                notice.setRemark("first定时任务生成");
                projectNoticeServie.insertSelective(notice);
            }
        }

    }

    public  List<SysUser>  getCheckUsers(String  roleName, SupplierProject  project){
        // 20220324 修改
        //2、中标审核人首先按照公司进行匹配，然后需按照供需中的业务类型对应部门进行分开审核
        //（1）中标审核人按照部门进行划分；比如监理类型->工程部；咨询类型->咨询部；检测类型->检测部；
        //（2）每个业务类型对应的部门审核人只有一个；
        //（3）如果业务类型只有一个，按照部门进行流程的分发；
        //（4）如果业务类型是复合型的，需要复合型的都审核完才行；
        SysUserDTO sysUserDTO = new SysUserDTO();
        // 中标审核人角色
        sysUserDTO.setUserRole(roleName);
        // 获取发布单位
        sysUserDTO.setCompanyName(project.getPublishCompany());

        // 获取项目类型
        String projectType = project.getProjectType();
        ArrayList<String>  listdept=new ArrayList<>();
        if(projectType.indexOf("001")!=-1){
            // 监理类型 对应工程部
            listdept.add("001");
        }
        if(projectType.indexOf("002")!=-1){
            listdept.add("003");
        }
        if(projectType.indexOf("003")!=-1){
            listdept.add("004");
        }
        String deptNames = StringUtils.join(listdept, ",");
        sysUserDTO.setDeptNames(deptNames);

        List<SysUser> sysUsers = sysUserService.getUserDicts(sysUserDTO);
        return sysUsers;
    }
        public void lock(String key, String uuId) {
            for (; ; ) {

                System.out.println(redisService);
                boolean r = stringRedisTemplate.opsForValue().setIfAbsent(key, uuId);
                stringRedisTemplate.expire(key, 600, TimeUnit.SECONDS);

                if (r) {
                    return;
                }else {
                    throw new RuntimeException("已经存在的执行程序...");
                }
            }
        }

        public void unlock(String key, String uuId) {
            if (uuId.equals(stringRedisTemplate.opsForValue().get(key))) {
                stringRedisTemplate.delete(key);
            }
        }
}
